<script setup lang="ts">
// 异常详情弹窗
import {computed, nextTick, reactive, ref, watch} from 'vue';
import mammoth from 'mammoth';
import _ from 'underscore';
import { errorMessage, escapeHTMLManually, generateRandomCode, getImageInfoFromBase64 } from '@/utils/utils';

interface Props {
  show?: boolean;
  checkContent?: any;
  selectedIndex?: number;
  selectedData?: any;
  compareData?: any;
}

const props = withDefaults(defineProps<Props>(), {
  show: false,
  checkContent: [],
  selectedIndex: 0,
  selectedData: {},
  compareData: {}
});

const showLoading = ref<boolean>(true);
const loadingDes = ref<string>('文档较大，正在努力处理中，请稍后...');
const isBack = ref<boolean>(false);
const fileList = ref<any[]>([]);

const leftDocContentHtml = ref<string>('');
const rightDocContentHtml = ref<string>('');
const leftAllContentHtml = ref<string>('');
const rightAllContentHtml = ref<string>('');
const leftContentHtml = ref<string>('');
const rightContentHtml = ref<string>('');
const leftImgList = ref<any[]>([]);
const rightImgList = ref<any[]>([]);
const IMAGE_TAG: string = 'IMAGE_TAG';

const bidUnitData = ref<any>({}); // 基准文件地址
const compareFile = ref<any>({}); // 投标单位

// 编辑器配置
const editorConfig: object = reactive({
  serverUrl: '',
  UEDITOR_HOME_URL: '/modules/bidWriting/UEditorPlus/',
  UEDITOR_CORS_URL: '/modules/bidWriting/UEditorPlus/',
  toolbars: [],
  readonly: true,
  autoFloatEnabled: false,
  autoSaveEnable: false, // 禁用自动保存
  elementPathEnabled: false, // 禁用元素路径
  initialFrameHeight: '510',
  autoHeightEnabled: false, // 禁止编辑器自动长高
  maximumWords: 2000000
});

// 引入的js文件，这里是一定要写的。
const editorDependencies: string[] = reactive(['ueditor.config.js', 'ueditor.all.js', 'lang/zh-cn/zh-cn.js']);

const leftUeditor = ref<any | null>(null);
const rightUeditor = ref<any | null>(null);

const topButtonList = ref<any[]>([]);
const currentButton = ref<number>(0);
const currentTab = ref<string>('');
const errorTypeList = ref<any[]>([]);
const currentErrorList = ref<any[]>([]);
const currentErrorIndex = ref<number | undefined>(undefined);
const currentErrorData = ref<any | null>(null);
const specialData = ref<any>({}); // 作者、时间相关信息

async function leftReadyHandle(editor: any) {
  leftUeditor.value = editor;

  for (let i: number = 0; i < bidUnitData.value.filePath.length; i++) {
    loadingDes.value = '文档较大，正在努力处理中，请稍后...';
    showLoading.value = true;
    const data = await getLeftHtmlByDocument(bidUnitData.value.fileName, bidUnitData.value.filePath[i]);
    if (i === bidUnitData.value.filePath.length - 1) {
      showLoading.value = false;
    }
  }
}

async function rightReadyHandle(editor: any) {
  rightUeditor.value = editor;

  const compareFileName: string = props.compareData.map[currentButton.value].compareName;
  const compareFilePath: string[] = props.compareData.map[currentButton.value].comparePath;
  const compareNum: number = props.compareData.map[currentButton.value].compare;
  compareFile.value = {
    compareNum,
    fileName: compareFileName,
    filePath: compareFilePath
  };
  for (let i: number = 0; i < compareFilePath.length; i++) {
    loadingDes.value = '文档较大，正在努力处理中，请稍后...';
    showLoading.value = true;
    const data = await getRightHtmlByDocument(compareFileName, compareFilePath[i]);
    if (i === compareFilePath.length - 1) {
      showLoading.value = false;
    }
  }
}

const titleMap: any[] = [
  {
    title: '正文相似量',
    key: 'zhengwen',
    index: 1
  },
  {
    title: '目录相似量',
    key: 'mulu',
    index: 2
  },
  {
    title: '字体字号相似量',
    key: 'zitizihao',
    index: 3
  },
  {
    title: '图片相似量',
    key: 'tupian',
    index: 4
  },
  {
    title: '批注识别',
    key: 'pizhu',
    index: 5
  },
  {
    title: '投标人名称查询',
    key: 'mingcheng',
    index: 6
  },
  {
    title: '投标人地址查询',
    key: 'dizhi',
    index: 7
  },
  {
    title: '法人查重',
    key: 'faren',
    index: 8
  },
  {
    title: '报价规律性',
    key: 'baojia',
    index: 9
  },
  {
    title: '投标保证金付款单位',
    key: 'baozhengjin',
    index: 10
  },
  {
    title: '投标文件编辑时间',
    key: 'shijian',
    index: 11
  },
  {
    title: '投标文件编辑作者',
    key: 'zuozhe',
    index: 12
  }
];

watch(
  () => props.show,
  value => {
    if (value) {
      dataProcessingHandle();
    } else {
      currentErrorData.value = null;
      topButtonList.value = [];
      errorTypeList.value = [];
      leftDocContentHtml.value = '';
      rightDocContentHtml.value = '';
      leftContentHtml.value = '';
      rightContentHtml.value = '';
      leftUeditor.value = null;
      rightUeditor.value = null;
      currentErrorIndex.value = undefined;
      fileList.value = [];
      errorTypeList.value = [];
    }
  }
);

// 数据处理
function dataProcessingHandle() {
  topButtonList.value = [];
  errorTypeList.value = [];

  isBack.value = false;
  leftDocContentHtml.value = '';
  rightDocContentHtml.value = '';
  leftContentHtml.value = '';
  rightContentHtml.value = '';
  leftAllContentHtml.value = '';
  rightAllContentHtml.value = '';
  currentErrorIndex.value = undefined;
  fileList.value = [];

  // console.log('props.checkContent: ', props.checkContent);
  // console.log('props.compareData: ', props.compareData);
  // console.log('props.selectedData: ', props.selectedData);

  currentButton.value = props.selectedIndex;
  currentTab.value = props.selectedData.compareKey;
  bidUnitData.value = {
    fileName: props.compareData.bidUnit,
    filePath: props.compareData.bidUnitPath
  };

  if (currentTab.value === 'zuozhe' || currentTab.value === 'shijian') {
    const authorData: any = props.compareData.map[currentButton.value].compareContent.zuozhe;
    const timeData: any = props.compareData.map[currentButton.value].compareContent.shijian;
    specialData.value = {
      author1: authorData.length > 0 ? authorData[0].author1 || '' : '',
      lastModifiedBy1: authorData.length > 0 ? authorData[0].lastModifiedBy1 || '' : '',
      createdTime1: timeData.length > 0 ? timeData[0].createdTime1 || '' : '',
      modifiedTime1: timeData.length > 0 ? timeData[0].modifiedTime1 || '' : '',
      author2: authorData.length > 0 ? authorData[0].author2 || '' : '',
      lastModifiedBy2: authorData.length > 0 ? authorData[0].lastModifiedBy2 || '' : '',
      createdTime2: timeData.length > 0 ? timeData[0].createdTime2 || '' : '',
      modifiedTime2: timeData.length > 0 ? timeData[0].modifiedTime2 || '' : ''
    };
  }

  for (let i: number = 0; i < props.compareData.map.length; i++) {
    const itemData: string = props.compareData.map[i];
    const errorNum: number = itemData.compareErrorNumber ? Number.parseInt(itemData.compareErrorNumber, 10) : 0;
    const buttonObj: any = {
      id: generateRandomCode(3, 'numEML'),
      buttonName: `投标单位${itemData.compare}(${errorNum}个异常)`,
      fileName: itemData.compareName,
      filePath: itemData.comparePath
    };
    topButtonList.value.push(buttonObj);
  }

  for (let i: number = 0; i < props.checkContent.length; i++) {
    const itemData: any = props.checkContent[i];
    for (let j: number = 0; j < titleMap.length; j++) {
      const titleItem: any = titleMap[j];
      if (itemData === titleItem.key) {
        const buttonObj: any = {
          id: generateRandomCode(3, 'numEML'),
          title: titleItem.title,
          key: itemData,
          index: titleItem.index
        };

        errorTypeList.value.push(buttonObj);
        break;
      }
    }
  }

  const errorData: any = props.compareData.map[currentButton.value].compareContent;
  currentErrorList.value = errorData[currentTab.value];

  for (const errorKey in errorData) {
    if (Object.hasOwn(errorData, errorKey)) {
      for (let i: number = 0; i < errorTypeList.value.length; i++) {
        const item: any = errorTypeList.value[i];
        if (item.key === errorKey) {
          item.errorNum = errorData[errorKey].length;
          break;
        }
      }
    }
  }

  // 排序
  errorTypeList.value.sort((a: any, b: any) => {
    return a.index - b.index;
  });

  // console.log('errorTypeList: ', errorTypeList);
}

// 根据文档获取html内容
function getLeftHtmlByDocument(fileName: string, filePath: string) {
  const { VITE_OTHER_SERVICE_BASE_URL } = import.meta.env;
  const otherUrl = JSON.parse(VITE_OTHER_SERVICE_BASE_URL);
  const docPath: string = otherUrl.fileUrl + filePath;

  return new Promise((resolve, reject) => {
    fetch(docPath, { cache: 'no-cache' })
      .then(response => response.blob())
      .then(blobData => {
        let file: File | null = new File([blobData], `${fileName}.docx`, {
          type: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
          lastModified: Date.now()
        });

        leftAnalysisWord(file)
          .then(html => {
            // console.log("html: ", html);

            for (let i: number = 0; i < leftImgList.value.length; i++) {
              leftDocContentHtml.value = leftDocContentHtml.value.replace(IMAGE_TAG, leftImgList.value[i]);
            }
            leftDocContentHtml.value = leftDocContentHtml.value.replace(/style=""/g, '');
            leftAllContentHtml.value += leftDocContentHtml.value;
            // 设置内容到编辑器中
            leftUeditor.value.setContent(leftDocContentHtml.value, true);
            contentDomOptimize(leftUeditor.value);
            // compareErrorMarkAction(leftUeditor.value, 0);
            resolve(true);
            // showLoading.value = false;
            // ueditor.value.execCommand('inserthtml', writeContentHtml.value); // 插入文本
          })
          .catch(error => {
            resolve(false);
            // showLoading.value = false;
          });

        // 文件信息置空
        file = null;
      })
      .catch(error => {
        console.error('发生错误：', error);
        // showLoading.value = false;
        errorMessage('获取文档失败');
        reject(error);
      });
  });
}

// 根据文档获取html内容
function getRightHtmlByDocument(fileName: string, filePath: string) {
  const { VITE_OTHER_SERVICE_BASE_URL } = import.meta.env;
  const otherUrl = JSON.parse(VITE_OTHER_SERVICE_BASE_URL);
  const docPath: string = otherUrl.fileUrl + filePath;

  return new Promise((resolve, reject) => {
    fetch(docPath, { cache: 'no-cache' })
      .then(response => response.blob())
      .then(blobData => {
        let file: File | null = new File([blobData], `${fileName}.docx`, {
          type: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
          lastModified: Date.now()
        });

        rightAnalysisWord(file)
          .then(html => {
            // console.log("html: ", html);

            for (let i: number = 0; i < rightImgList.value.length; i++) {
              rightDocContentHtml.value = rightDocContentHtml.value.replace(IMAGE_TAG, rightImgList.value[i]);
            }
            rightDocContentHtml.value = rightDocContentHtml.value.replace(/style=""/g, '');
            rightAllContentHtml.value += rightDocContentHtml.value;
            rightUeditor.value.setContent(rightDocContentHtml.value, true);
            contentDomOptimize(rightUeditor.value);
            // compareErrorMarkAction(rightUeditor.value, 1);
            resolve(true);
            // showLoading.value = false;
            // ueditor.value.execCommand('inserthtml', writeContentHtml.value); // 插入文本
          })
          .catch(error => {
            // showLoading.value = false;
            resolve(false);
          });

        // 文件信息置空
        file = null;
      })
      .catch(error => {
        console.error('发生错误：', error);
        // showLoading.value = false;
        errorMessage('获取文档失败');
        reject(error);
      });
  });
}

// 解析word文件，将word转为html
function leftAnalysisWord(file: any) {
  return new Promise(resolve => {
    const reader = new FileReader();
    reader.onload = evt => {
      // console.log('evt：', evt);
      // 当文件读取完毕后
      // p标签首行没有缩进
      const options = {
        transformDocument: leftTransformElement,
        styleMap: ["p[style-name='Section Title'] => h1:fresh", "p[style-name='Subsection Title'] => h2:fresh"]
      };

      // 调用mammoth组件的方法进行解析文件
      mammoth
        .convertToHtml({ arrayBuffer: evt.target!.result }, options)
        .then(resultObject => {
          // console.log("resultObject: ", resultObject);
          // resultObject.value = imgTagAddStyle(resultObject.value);
          const imgSrcReg = /<img[^>]+src=[\\'|\\"]?([^(?"|?'|?>)]+)[\\'|\\"]?[^>]*>/gim;
          const imgSrcList = resultObject.value.match(imgSrcReg);

          if (imgSrcList) {
            leftImgList.value = imgSrcList;
          }

          resolve(resultObject.value); // 将处理好的html数据返回
          reader.abort(); // 关闭读取
        })
        .catch(err => {
          // console.log('err: ', err);
          reader.abort(); // 关闭读取
        });
    };
    reader.readAsArrayBuffer(file);
    // 启动读取指定的 Blob 或 File 内容：https://developer.mozilla.org/zh-CN/docs/Web/API/FileReader/readAsArrayBuffer
  });
}

// 解析word文件，将word转为html
function rightAnalysisWord(file: any) {
  return new Promise(resolve => {
    const reader = new FileReader();
    reader.onload = evt => {
      // console.log('evt：', evt);
      // 当文件读取完毕后
      // p标签首行没有缩进
      const options = {
        transformDocument: rightTransformElement,
        styleMap: ["p[style-name='Section Title'] => h1:fresh", "p[style-name='Subsection Title'] => h2:fresh"]
      };

      // 调用mammoth组件的方法进行解析文件
      mammoth
        .convertToHtml({ arrayBuffer: evt.target!.result }, options)
        .then(resultObject => {
          // console.log("resultObject: ", resultObject);
          // resultObject.value = imgTagAddStyle(resultObject.value);
          const imgSrcReg = /<img[^>]+src=[\\'|\\"]?([^(?"|?'|?>)]+)[\\'|\\"]?[^>]*>/gim;
          const imgSrcList = resultObject.value.match(imgSrcReg);

          if (imgSrcList) {
            rightImgList.value = imgSrcList;
          }

          resolve(resultObject.value); // 将处理好的html数据返回
          reader.abort(); // 关闭读取
        })
        .catch(err => {
          // console.log('err: ', err);
          reader.abort(); // 关闭读取
        });
    };
    reader.readAsArrayBuffer(file);
    // 启动读取指定的 Blob 或 File 内容：https://developer.mozilla.org/zh-CN/docs/Web/API/FileReader/readAsArrayBuffer
  });
}

// 元素重新定义
function leftTransformElement(element: any) {
  if (element.children) {
    const children: any = _.map(element.children, leftTransformElement);
    element = { ...element, children };
  }

  if (element.type === 'paragraph') {
    element = transformParagraph(element);
  }

  if (element.type === 'document') {
    // docParagraphList.value = element.children;
    // console.log('docParagraphList.value: ', element.children);
    leftHtmlFormat(element.children);
  }

  return element;
}

// 元素重新定义
function rightTransformElement(element: any) {
  if (element.children) {
    const children: any = _.map(element.children, rightTransformElement);
    element = { ...element, children };
  }

  if (element.type === 'paragraph') {
    element = transformParagraph(element);
  }

  if (element.type === 'document') {
    // docParagraphList.value = element.children;
    // console.log('docParagraphList.value: ', element.children);
    rightHtmlFormat(element.children);
  }

  return element;
}

// 段落内容重新定义
function transformParagraph(element: any) {
  if (element.alignment === 'center' && !element.styleId) {
    return { ...element, styleId: 'Heading2' };
  }
  return element;
}

// 根据文档解析API进行HTML内容拼接封装
function leftHtmlFormat(docParagraphList: any[]) {
  let docHtmlStr: string = '';
  for (let i: number = 0; i < docParagraphList.length; i++) {
    const paragraphObj: any = docParagraphList[i];
    if (paragraphObj.type === 'paragraph') {
      // 普通段落内容（包括文字和图片）
      let paragraphStr: string = '';
      let alignmentStr: string = '';
      if (paragraphObj.alignment) {
        alignmentStr = `text-align: ${paragraphObj.alignment}; line-height: 150%; align-items: baseline;`;
      } else {
        alignmentStr = 'text-align: left; line-height: 150%; align-items: baseline;';
      }

      for (let j: number = 0; j < paragraphObj.children.length; j++) {
        if (paragraphObj.children.length > 1 && j === 0 && paragraphObj.indent.firstLine) {
          alignmentStr = 'text-indent: 2em;';
        }
        const formatContent = paragraphHtmlFormat(paragraphObj.children[j]);
        if (formatContent === IMAGE_TAG) {
          alignmentStr = 'display: block;text-align: center;';
        }
        paragraphStr += formatContent;
      }
      if (paragraphObj.styleId === 'Heading1' || paragraphObj.styleName === 'heading 1') {
        docHtmlStr += `<h1 style="${alignmentStr}">${paragraphStr}</h1>`;
      } else if (paragraphObj.styleId === 'Heading2' || paragraphObj.styleName === 'heading 2') {
        docHtmlStr += `<h2 style="${alignmentStr}">${paragraphStr}</h2>`;
      } else if (paragraphObj.styleId === 'Heading3' || paragraphObj.styleName === 'heading 3') {
        docHtmlStr += `<h3 style="${alignmentStr}">${paragraphStr}</h3>`;
      } else if (paragraphObj.styleId === 'Heading4' || paragraphObj.styleName === 'heading 4') {
        docHtmlStr += `<h4 style="${alignmentStr}">${paragraphStr}</h4>`;
      } else if (paragraphObj.styleId === 'Heading5' || paragraphObj.styleName === 'heading 5') {
        docHtmlStr += `<h5 style="${alignmentStr}">${paragraphStr}</h5>`;
      } else if (paragraphObj.styleId === 'Heading6' || paragraphObj.styleName === 'heading 6') {
        docHtmlStr += `<h6 style="${alignmentStr}">${paragraphStr}</h6>`;
      } else {
        docHtmlStr += `<p style="${alignmentStr}">${paragraphStr}</p>`;
      }
    } else if (paragraphObj.type === 'table') {
      // 表格内容处理
      const tableObj: any = docParagraphList[i];
      docHtmlStr += tableHtmlFormat(tableObj);
    }
  }
  leftDocContentHtml.value = `<div style="margin: 72pt;">${docHtmlStr}</div>`;
}

// 根据文档解析API进行HTML内容拼接封装
function rightHtmlFormat(docParagraphList: any[]) {
  let docHtmlStr: string = '';
  for (let i: number = 0; i < docParagraphList.length; i++) {
    const paragraphObj: any = docParagraphList[i];
    if (paragraphObj.type === 'paragraph') {
      // 普通段落内容（包括文字和图片）
      let paragraphStr: string = '';
      let alignmentStr: string = '';
      if (paragraphObj.alignment) {
        alignmentStr = `text-align: ${paragraphObj.alignment}; line-height: 150%; align-items: baseline;`;
      } else {
        alignmentStr = 'text-align: left; line-height: 150%; align-items: baseline;';
      }

      for (let j: number = 0; j < paragraphObj.children.length; j++) {
        if (paragraphObj.children.length > 1 && j === 0 && paragraphObj.indent.firstLine) {
          alignmentStr = 'text-indent: 2em;';
        }
        const formatContent = paragraphHtmlFormat(paragraphObj.children[j]);
        if (formatContent === IMAGE_TAG) {
          alignmentStr = 'display: block;text-align: center;';
        }
        paragraphStr += formatContent;
      }
      if (paragraphObj.styleId === 'Heading1' || paragraphObj.styleName === 'heading 1') {
        docHtmlStr += `<h1 style="${alignmentStr}">${paragraphStr}</h1>`;
      } else if (paragraphObj.styleId === 'Heading2' || paragraphObj.styleName === 'heading 2') {
        docHtmlStr += `<h2 style="${alignmentStr}">${paragraphStr}</h2>`;
      } else if (paragraphObj.styleId === 'Heading3' || paragraphObj.styleName === 'heading 3') {
        docHtmlStr += `<h3 style="${alignmentStr}">${paragraphStr}</h3>`;
      } else if (paragraphObj.styleId === 'Heading4' || paragraphObj.styleName === 'heading 4') {
        docHtmlStr += `<h4 style="${alignmentStr}">${paragraphStr}</h4>`;
      } else if (paragraphObj.styleId === 'Heading5' || paragraphObj.styleName === 'heading 5') {
        docHtmlStr += `<h5 style="${alignmentStr}">${paragraphStr}</h5>`;
      } else if (paragraphObj.styleId === 'Heading6' || paragraphObj.styleName === 'heading 6') {
        docHtmlStr += `<h6 style="${alignmentStr}">${paragraphStr}</h6>`;
      } else {
        docHtmlStr += `<p style="${alignmentStr}">${paragraphStr}</p>`;
      }
    } else if (paragraphObj.type === 'table') {
      // 表格内容处理
      const tableObj: any = docParagraphList[i];
      docHtmlStr += tableHtmlFormat(tableObj);
    }
  }
  rightDocContentHtml.value = `<div style="margin: 72pt;">${docHtmlStr}</div>`;
}

// 段落内容格式化
function paragraphHtmlFormat(paragraphObj: any) {
  let contentStr: string = '';

  // console.log("paragraphObj: ", paragraphObj);
  // type类型太多，虽然可以兼容大部分情况，但是偶然还会出现一些奇奇怪怪的type值
  if (!paragraphObj.children) {
    return '<span></span>';
  }

  if (paragraphObj.children.length === 0) {
    return '<br/>';
  }

  for (let i: number = 0; i < paragraphObj.children.length; i++) {
    if (paragraphObj.children[i].type === 'text') {
      let textStr: string = paragraphObj.children[i].value;
      // 如果有html字符串，将其解析为html字符串，就可以正常展示
      textStr = escapeHTMLManually(textStr);

      let styleStr: string = `line-height: 150%;`;
      if (paragraphObj.font) {
        styleStr += `font-family: ${paragraphObj.font};`;
      }
      if (paragraphObj.fontSize) {
        styleStr += `font-size: ${paragraphObj.fontSize}pt;`;
      }
      // 是否有下划线
      if (paragraphObj.isUnderline) {
        styleStr += 'text-decoration: underline;';
      }
      // 是否有删除线
      if (paragraphObj.isStrikethrough) {
        styleStr += 'text-decoration: line-through;';
      }
      // if (paragraphObj.verticalAlignment) {
      //   styleStr += `display: block; align-items: ${paragraphObj.verticalAlignment};`;
      // }
      /** font: "fzxbsjw-gb1-0" fontSize: 32 */
      // 文档标题设置固定的色值：#E03E2D
      if (paragraphObj.fontSize === 32 && paragraphObj.font === 'fzxbsjw-gb1-0') {
        styleStr += 'color: #E03E2D;';
      }
      // 是否加粗
      if (paragraphObj.isBold) {
        styleStr += 'font-weight: bold;';
      }
      contentStr += `<span style="${styleStr}">${textStr}</span>`;
    } else if (paragraphObj.children[i].type === 'hyperlink') { // 超链接
      paragraphHtmlFormat(paragraphObj.children[i]);
    } else if (paragraphObj.children[i].type === 'break') {
      // 换行
      contentStr += '<br/>';
    } else if (paragraphObj.children[i].type === 'image') {
      // 图片
      contentStr += IMAGE_TAG;
    } else {
      contentStr = String(contentStr);
    }
  }

  return contentStr;
}

// 表格内容格式化
function tableHtmlFormat(tableObj: any) {
  let tableStr: string = '';
  for (let i: number = 0; i < tableObj.children.length; i++) {
    // 遍历 tableRow
    const rowObj: any = tableObj.children[i];
    if (rowObj.isHeader) {
      tableStr += '<thead><tr>';
    } else {
      tableStr += '<tbody><tr>';
    }
    for (let j: number = 0; j < rowObj.children.length; j++) {
      // 遍历 tableCell
      const cellObj: any = rowObj.children[j];
      if (rowObj.isHeader) {
        tableStr += `<th>`;
      } else {
        tableStr += `<td>`;
      }
      for (let k: number = 0; k < cellObj.children.length; k++) {
        const contentObj: any = cellObj.children[k];

        let paragraphStr: string = '';
        let alignmentStr: string = '';
        if (contentObj.alignment) {
          alignmentStr = `text-align: ${contentObj.alignment};`;
        } else {
          alignmentStr = 'text-align: left;';
        }
        for (let l: number = 0; l < contentObj.children.length; l++) {
          if (contentObj.children.length > 1 && l === 0 && contentObj.indent && contentObj.indent.firstLine) {
            alignmentStr += 'text-indent: 2em;';
          }
          paragraphStr += paragraphHtmlFormat(contentObj.children[l]);
        }
        tableStr += `<p style="${alignmentStr}">${paragraphStr}</p>`;
      }
      if (rowObj.isHeader) {
        tableStr += '</th>';
      } else {
        tableStr += '</td>';
      }
    }
    if (rowObj.isHeader) {
      tableStr += '</tr></thead>';
    } else {
      tableStr += '</tr></tbody>';
    }
  }
  return `<table style="width: 100%; border-collapse: collapse;">${tableStr}</table>`;
}

const emit = defineEmits(['update:show']);

const modalShowValue = computed({
  get() {
    return props.show;
  },
  set(value: boolean) {
    emit('update:show', value);
  }
});

// 顶部比对文件点击
async function topCompareFileClick(index: number) {
  if (currentButton.value === index) return;
  currentButton.value = index;

  const compareFileName: string = props.compareData.map[currentButton.value].compareName;
  const compareFilePath: string = props.compareData.map[currentButton.value].comparePath;
  const compareNum: number = props.compareData.map[currentButton.value].compare;
  compareFile.value = {
    compareNum,
    fileName: compareFileName,
    filePath: compareFilePath
  };

  const errorData: any = props.compareData.map[currentButton.value].compareContent;
  currentTab.value = errorTypeList.value[0].key;
  currentErrorList.value = errorData[currentTab.value];
  currentErrorIndex.value = undefined;
  currentErrorData.value = null;

  for (const errorKey in errorData) {
    if (Object.hasOwn(errorData, errorKey)) {
      for (let i: number = 0; i < errorTypeList.value.length; i++) {
        const item: any = errorTypeList.value[i];
        if (item.key === errorKey) {
          item.errorNum = errorData[errorKey].length;
          break;
        }
      }
    }
  }

  // 左侧编辑器内容标记
  // await compareErrorMarkAction(leftUeditor.value, 0);

  // 先清空编辑器再加载数据
  rightUeditor.value.clear();
  rightAllContentHtml.value = '';
  for (let i: number = 0; i < compareFilePath.length; i++) {
    loadingDes.value = '文档较大，正在努力处理中，请稍后...';
    showLoading.value = true;
    const data = await getRightHtmlByDocument(compareFileName, compareFilePath[i]);
    if (i === compareFilePath.length - 1) {
      showLoading.value = false;
    }
  }
}

// 顶部错误类型点击事件
async function tabChangeHandle(value: string) {
  // console.log('value: ', value);
  currentErrorList.value = props.compareData.map[currentButton.value].compareContent[value];
  currentErrorIndex.value = undefined;
  currentErrorData.value = null;

  if (value === 'zuozhe' || value === 'shijian') {
    const authorData: any = props.compareData.map[currentButton.value].compareContent.zuozhe;
    const timeData: any = props.compareData.map[currentButton.value].compareContent.shijian;
    specialData.value = {
      author1: authorData.length > 0 ? authorData[0].author1 || '' : '',
      lastModifiedBy1: authorData.length > 0 ? authorData[0].lastModifiedBy1 || '' : '',
      createdTime1: timeData.length > 0 ? timeData[0].createdTime1 || '' : '',
      modifiedTime1: timeData.length > 0 ? timeData[0].modifiedTime1 || '' : '',
      author2: authorData.length > 0 ? authorData[0].author2 || '' : '',
      lastModifiedBy2: authorData.length > 0 ? authorData[0].lastModifiedBy2 || '' : '',
      createdTime2: timeData.length > 0 ? timeData[0].createdTime2 || '' : '',
      modifiedTime2: timeData.length > 0 ? timeData[0].modifiedTime2 || '' : ''
    };
  }

  // 文件拆分后，leftDocContentHtml和rightDocContentHtml只有最后一个切片文件的内容，需要一个新的字段去接收所有的HTML内容
  // 先清空编辑器再加载数据
  leftUeditor.value.clear();
  leftUeditor.value.setContent(leftAllContentHtml.value);
  leftUeditor.value.iframe.contentWindow.scrollTo(0, 0);
  // 先清空编辑器再加载数据
  rightUeditor.value.clear();
  rightUeditor.value.setContent(rightAllContentHtml.value);
  rightUeditor.value.iframe.contentWindow.scrollTo(0, 0);
}

// 获取编辑器iframe元素中的标签内容
function getIframeContent(editor: any) {
  // 获取编辑器iframe
  const iframe = editor.iframe;
  const iframeDoc = iframe.contentDocument || iframe.contentWindow.document;

  // 在iframe中查找对应文本
  const walker = document.createTreeWalker(iframeDoc.body, NodeFilter.SHOW_TEXT, null, false);
  return walker.root.childNodes;
}

const hTagList: string[] = ['H1', 'H2', 'H3', 'H4', 'H5', 'H6'];

// 内容Dom节点优化
function contentDomOptimize(editor: any) {
  const walkerNodes: any[] = getIframeContent(editor);

  for (let i: number = 0; i < walkerNodes.length; i++) {
    const node = walkerNodes[i];
    if (node.nodeName === 'P' || hTagList.includes(node.nodeName)) {
      spanDomOptimize(node);
    } else if (node.nodeName === 'TABLE') {
      // 表格
      const tableChildNode: any = node.childNodes;
      for (let j: number = 0; j < tableChildNode.length; j++) {
        const childNode: any = tableChildNode[j];
        if (childNode.nodeName === 'TR') {
          const trChildNode: any = childNode.childNodes;
          for (let k: number = 0; k < trChildNode.length; k++) {
            const tdNode: any = trChildNode[k];
            if (tdNode.nodeName === 'TD' || tdNode.nodeName === 'TH') {
              const tdChildNode: any = tdNode.childNodes;
              for (let m: number = 0; m < tdChildNode.length; m++) {
                const childNode: any = tdChildNode[m];
                if (childNode.nodeName === 'P' || hTagList.includes(childNode.nodeName)) {
                  spanDomOptimize(childNode);
                }
              }
            }
          }
        }
      }
    }
  }
}

// Span标签内容优化
function spanDomOptimize(node: any) {
  const textContent: string = node.textContent;
  let childNodeStyle: string = '';
  const childStyle: string[] = [];
  for (let j: number = 0; j < node.children.length; j++) {
    const childNode: any = node.children[j];
    if (childNode.getAttribute('style')) {
      childStyle.push(childNode.getAttribute('style'));
    } else {
      childStyle.push('');
    }
  }
  const newChildStyle: string[] = Array.from(new Set(childStyle));
  if (newChildStyle.length > 0) {
    if (newChildStyle.length === 1) {
      childNodeStyle = newChildStyle[0];

      while (node.firstChild && node.firstChild.nodeName === 'SPAN') {
        node.removeChild(node.firstChild);
      }

      const spanNode: any = document.createElement('span');
      spanNode.setAttribute('style', childNodeStyle);
      spanNode.textContent = textContent;
      node.append(spanNode);
    } else {
      // Warning: 暂不支持多样式合并
    }
  } else {
    while (node.firstChild && node.firstChild.nodeName === 'SPAN') {
      node.removeChild(node.firstChild);
    }

    const spanNode: any = document.createElement('span');
    spanNode.textContent = textContent;
    node.append(spanNode);
  }
}

// 特殊处理 标记、字体字号、作者、时间、图片
const specialTabList: string[] = ['zuozhe', 'shijian', 'tupian'];

/**
 * 正文内容标记
 *
 * @param editor 编辑器
 * @param checkStr 需要标记的文字串
 */
async function compareErrorMarkAction(editor: any, checkStr: string) {
  if (!checkStr) return;

  if (specialTabList.includes(currentTab.value)) {
    // 作者和时间直接展示内容
    // 图片只需要定位到第几张图片即可
    return;
  }

  const walkerNodes: any[] = getIframeContent(editor);

  for (let j: number = 0; j < walkerNodes.length; j++) {
    const childNode: any = walkerNodes[j];
    if (childNode.nodeName === 'P' || hTagList.includes(childNode.nodeName)) {
      pLabelNodeContentFormat(checkStr, childNode);
    } else if (childNode.nodeName === 'TABLE') {
      if (childNode.textContent.includes(checkStr)) {
        for (let k: number = 0; k < childNode.children.length; k++) {
          const tableRow: any = childNode.children[k]; // TBODY
          for (let l: number = 0; l < tableRow.children.length; l++) {
            const tableCell: any = tableRow.children[l]; // TR
            for (let m: number = 0; m < tableCell.children.length; m++) {
              const tdContent: any = tableCell.children[m]; // TD
              for (let n: number = 0; n < tdContent.children.length; n++) {
                const cellContent: any = tdContent.children[n];
                if (cellContent.nodeName === 'P' || hTagList.includes(cellContent.nodeName)) {
                  pLabelNodeContentFormat(checkStr, cellContent);
                }
              }
            }
          }
        }
      }
    }
  }
}

let nodeIndex: number = 0;

// P标签内容标记
function pLabelNodeContentFormat(checkStr: string, childNode: any) {
  if (!checkStr) return;

  if (childNode.textContent.length >= checkStr.length) {
    if (childNode.textContent.includes(checkStr)) {
      const labelTextContent: string = childNode.textContent;
      let childNodeStyle: string = '';

      if (childNode && childNode.children && childNode.children.length > 0) {
        if (childNode.children.length === 1) {
          const childrenNodeStyle = childNode.children[0].getAttribute('style');

          childNodeStyle = contentColorHandle(childrenNodeStyle);

          const startIndex: number = labelTextContent.indexOf(checkStr);
          const endIndex: number = startIndex + checkStr.length;

          const startNode: any = document.createElement('span');
          startNode.textContent = labelTextContent.substring(0, startIndex);
          startNode.setAttribute('style', childrenNodeStyle);
          if (startNode.textContent.length > 0) {
            childNode.appendChild(startNode);
          }

          const centerNode: any = document.createElement('span');
          if (childNodeStyle !== '') {
            centerNode.setAttribute('style', childNodeStyle);
          }
          centerNode.textContent = labelTextContent.substring(startIndex, endIndex);
          childNode.appendChild(centerNode);

          const endNode: any = document.createElement('span');
          endNode.textContent = labelTextContent.substring(endIndex);
          endNode.setAttribute('style', childrenNodeStyle);
          if (endNode.textContent.length > 0) {
            childNode.appendChild(endNode);
          }

          childNode.removeChild(childNode.children[0]);
        } else {
          // TODO 增加递归使整个节点内容都被处理
          nodeIndex = 0;
          multiContentNodeFormat(checkStr, childNode, nodeIndex);
        }
      }
    }
  } else if (checkStr.includes(childNode.textContent)) {
    // const labelTextContent: string = childNode.textContent;
    // if (labelTextContent === '') return;
    // nodeIndex = 0;
    // multiContentNodeFormat(item, childNode, nodeIndex);
  }
}

// 多片段内容处理
function multiContentNodeFormat(checkStr: string, childNode: any, index: number) {
  if (!checkStr) return;

  if (index >= childNode.children.length) return;

  let targetNode: any = null;
  const spanChildNode = childNode.children[index];
  if (spanChildNode.nodeName === 'SPAN') {
    const spanChildText: string = trimPunctuation(spanChildNode.textContent);
    if (checkStr.length >= spanChildText.length) {
      if (checkStr.includes(spanChildText)) {
        targetNode = spanChildNode;
      }
    } else if (spanChildText.includes(checkStr)) {
      targetNode = spanChildNode;
    }

    if (targetNode) {
      const targetText: string = targetNode.textContent;
      const targetNodeStyle: string = targetNode.getAttribute('style');

      const spanNodeStyle: string = contentColorHandle(targetNodeStyle);

      const targetContentText: string = trimPunctuation(targetText);

      if (checkStr.length >= targetContentText.length) {
        const centerSpanNode: any = document.createElement('span');
        if (spanNodeStyle !== '') {
          centerSpanNode.setAttribute('style', spanNodeStyle);
        }
        centerSpanNode.textContent = targetText;
        childNode.replaceChild(centerSpanNode, targetNode);
      } else {
        const startIndex: number = targetText.indexOf(checkStr);
        const endIndex: number = startIndex + checkStr.length;

        const endSpanNode: any = document.createElement('span');
        endSpanNode.textContent = targetText.substring(endIndex);
        endSpanNode.setAttribute('style', targetNodeStyle);
        if (endSpanNode.textContent.length > 0) {
          childNode.insertBefore(endSpanNode, targetNode);
        }

        const centerSpanNode: any = document.createElement('span');
        if (spanNodeStyle !== '') {
          centerSpanNode.setAttribute('style', spanNodeStyle);
        }
        centerSpanNode.textContent = targetText.substring(startIndex, endIndex);
        if (endSpanNode.textContent.length > 0) {
          childNode.insertBefore(centerSpanNode, endSpanNode);
        } else {
          childNode.insertBefore(centerSpanNode, targetNode);
        }

        const startSpanNode: any = document.createElement('span');
        startSpanNode.textContent = targetText.substring(0, startIndex);
        startSpanNode.setAttribute('style', targetNodeStyle);
        if (startIndex > 0) {
          childNode.insertBefore(startSpanNode, centerSpanNode);
        }

        childNode.removeChild(targetNode);

        // multiContentNodeFormat(item, childNode, nodeIndex);
      }
      nodeIndex += 1;
      multiContentNodeFormat(checkStr, childNode, nodeIndex);
    } else {
      nodeIndex += 1;
      multiContentNodeFormat(checkStr, childNode, nodeIndex);
    }
  } else {
    nodeIndex += 1;
    multiContentNodeFormat(checkStr, childNode, nodeIndex);
  }
}

// 去除字符串中的标点符号
function trimPunctuation(str: string) {
  return str.replace(/^[\p{P}\p{S}\s]+|[\p{P}\p{S}\s]+$/gu, '');
}

// 内容颜色处理
function contentColorHandle(nodeStyle: string) {
  let spanNodeStyle: string = '';
  if (nodeStyle.includes('color: #FF7575;')) {
    spanNodeStyle = nodeStyle.replace('color: #FF7575;', '');
  }

  spanNodeStyle = `${nodeStyle}color: #FF7575;`;

  return spanNodeStyle;
}

// 搜索并定位（查找）
async function locateSentenceClick(item: any, index: number) {
  currentErrorIndex.value = index;

  // 先清空编辑器再加载数据
  leftUeditor.value.clear();
  await leftUeditor.value.setContent(leftAllContentHtml.value);

  // 先清空编辑器再加载数据
  rightUeditor.value.clear();
  await rightUeditor.value.setContent(rightAllContentHtml.value);

  currentErrorData.value = null;
  const similarityPercentageNum: number = item.similarityPercentage ? Number.parseFloat(item.similarityPercentage) : 0;
  item.plagiarismRateNum = Number.parseFloat((similarityPercentageNum * 100).toFixed(2));
  currentErrorData.value = item;

  // 作者和时间直接展示内容
  // 图片只需要定位到第几张图片即可
  if (currentTab.value === 'zuozhe' || currentTab.value === 'shijian') return;

  if (currentTab.value === 'zitizihao') {
    // 内容标记
    for (let i: number = 0; i < item.doc1List.length; i++) {
      await compareErrorMarkAction(leftUeditor.value, item.doc1List[i]);
    }

    for (let i: number = 0; i < item.doc2List.length; i++) {
      await compareErrorMarkAction(rightUeditor.value, item.doc2List[i]);
    }
  } else {
    // 内容标记
    await compareErrorMarkAction(leftUeditor.value, item.doc1Sentence);
    await compareErrorMarkAction(rightUeditor.value, item.doc2Sentence);
  }

  if (currentTab.value === 'tupian') {
    await locatePictureHandle(leftUeditor.value, Number.parseInt(item.doc1ImagId, 10));
    await locatePictureHandle(rightUeditor.value, Number.parseInt(item.doc2ImagId, 10));
  } else if (currentTab.value === 'zitizihao') {
    if (item.doc1List.length > 0) {
      await searchAndLocateSentenceClick(leftUeditor.value, item.doc1List[0], 1);
    }
    if (item.doc2List.length > 0) {
      await searchAndLocateSentenceClick(rightUeditor.value, item.doc2List[0], 1);
    }
  } else {
    const doc1Type: number = item.doc1Type ? Number.parseInt(item.doc1Type, 10) : 3;
    const doc2Type: number = item.doc2Type ? Number.parseInt(item.doc2Type, 10) : 3;
    await searchAndLocateSentenceClick(leftUeditor.value, item.doc1Sentence, doc1Type);
    await searchAndLocateSentenceClick(rightUeditor.value, item.doc2Sentence, doc2Type);
  }
}

// 搜索并定位（查找）
function searchAndLocateSentenceClick(editor: any, checkStr: string, type: number) {
  if (!checkStr) return;

  const content = editor.getContentTxt();
  const startIndex = content.indexOf(checkStr);

  if (startIndex !== -1) {
    const walkerNodes: any[] = getIframeContent(editor);

    let node;
    let offsetTop: number = 0;
    for (let j: number = 0; j < walkerNodes.length; j++) {
      const childNode: any = walkerNodes[j];
      if ((childNode.nodeName === 'P' || hTagList.includes(childNode.nodeName)) && (type === 1 || type === 3)) {
        if (childNode.textContent && childNode.textContent.includes(checkStr)) {
          node = childNode;
          offsetTop = node.offsetTop;
          break;
        }
      } else if (childNode.nodeName === 'TABLE' && (type === 2 || type === 3)) {
        try {
          if (childNode.textContent && childNode.textContent.includes(checkStr)) {
            for (let k: number = 0; k < childNode.children.length; k++) {
              const tableRow: any = childNode.children[k]; // TBODY
              for (let l: number = 0; l < tableRow.children.length; l++) {
                const tableCell: any = tableRow.children[l]; // TR
                for (let m: number = 0; m < tableCell.children.length; m++) {
                  const tdContent: any = tableCell.children[m]; // TD
                  for (let n: number = 0; n < tdContent.children.length; n++) {
                    const cellContent: any = tdContent.children[n];
                    if (cellContent.nodeName === 'P' || hTagList.includes(cellContent.nodeName)) {
                      if (cellContent.textContent && cellContent.textContent.includes(checkStr)) {
                        const position = getElementPosition(tableCell, childNode);
                        // 抛出异常的方式中断整个嵌套循环
                        throw {
                          name: 'searchResult',
                          node: cellContent,
                          offsetTop: childNode.offsetTop + position.top
                        };
                      }
                    }
                  }
                }
              }
            }
          }
        } catch (error: any) {
          if (error.name === 'searchResult') {
            node = error.node;
            offsetTop = error.offsetTop;
            break;
          }
        }
      }
    }

    if (node) {
      // 获取编辑器iframe
      const iframe = editor.iframe;
      // iframe.contentWindow.innerHeight / 2.0
      iframe.contentWindow.scrollTo(0, offsetTop - 20);
    }
  } else {
    console.log('未找到指定内容');
  }
}

// 查找并定位到指定图片
async function locatePictureHandle(editor: any, index: number) {
  const walkerNodes: any[] = await getIframeContent(editor);

  // console.log('walkerNodes: ', walkerNodes);
  const allImgNode: any[] = [];

  for (let j: number = 0; j < walkerNodes.length; j++) {
    const childNode: any = walkerNodes[j];
    if (childNode.nodeName === 'P' || hTagList.includes(childNode.nodeName)) {
      for (let i: number = 0; i < childNode.childNodes.length; i++) {
        const childNodeObj: any = childNode.childNodes[i];
        if (childNodeObj.nodeName === 'IMG') {
          const imageObj: any = {
            node: childNodeObj,
            offsetTop: childNodeObj.offsetTop
          };
          allImgNode.push(imageObj);
        }
      }
    } else if (childNode.nodeName === 'TABLE') {
      for (let k: number = 0; k < childNode.children.length; k++) {
        const tableRow: any = childNode.children[k]; // TBODY
        for (let l: number = 0; l < tableRow.children.length; l++) {
          const tableCell: any = tableRow.children[l]; // TR
          for (let m: number = 0; m < tableCell.children.length; m++) {
            const tdContent: any = tableCell.children[m]; // TD
            for (let n: number = 0; n < tdContent.children.length; n++) {
              const cellContent: any = tdContent.children[n];
              if (cellContent.nodeName === 'P' || hTagList.includes(cellContent.nodeName)) {
                for (let i: number = 0; i < cellContent.childNodes.length; i++) {
                  const cellContentChildNodes: any[] = cellContent.childNodes[i];
                  if (cellContentChildNodes.nodeName === 'IMG') {
                    const imageObj: any = {
                      node: cellContentChildNodes,
                      offsetTop: cellContentChildNodes.offsetTop + childNode.offsetTop
                    };
                    allImgNode.push(imageObj);
                  }
                }
              }
            }
          }
        }
      }
    }
  }

  // console.log('allImgNode: ', allImgNode, index);

  for (let i: number = 0; i < allImgNode.length; i++) {
    if (i === index - 1) {
      // 获取编辑器iframe
      const iframe = editor.iframe;
      // iframe.contentWindow.innerHeight / 2.0
      iframe.contentWindow.scrollTo(0, allImgNode[i].offsetTop - 15);
    }
  }
}

// 获取表格元素在表格中的相对位置
function getElementPosition(element: any, table: any) {
  let top = element.offsetTop;
  let left = element.offsetLeft;
  let parent = element.offsetParent;

  while (parent && parent !== table) {
    top += parent.offsetTop;
    left += parent.offsetLeft;
    parent = parent.offsetParent;
  }

  return { top, left };
}

// 取消
function closeModal() {
  isBack.value = true;

  currentErrorData.value = null;
  topButtonList.value = [];
  errorTypeList.value = [];
  leftDocContentHtml.value = '';
  rightDocContentHtml.value = '';
  leftContentHtml.value = '';
  rightContentHtml.value = '';
  leftAllContentHtml.value = '';
  rightAllContentHtml.value = '';
  leftUeditor.value = null;
  rightUeditor.value = null;
  currentErrorIndex.value = undefined;
  fileList.value = [];
  errorTypeList.value = [];
  // ueditor.value.destroy();
  // ueditor.value = null;
  modalShowValue.value = false;
}
</script>

<template>
  <NModal
    v-if="modalShowValue"
    v-model:show="modalShowValue"
    preset="card"
    title="异常详情"
    class="h-785px w-1700px"
    :mask-closable="false"
    @close="closeModal"
  >
    <div class="flex flex-col">
      <div class="top-btn-box">
        <NButton
          v-for="(item, index) in topButtonList"
          :key="item.id"
          class="head-btn"
          :class="currentButton === index ? 'head-btn-active' : ''"
          quaternary
          @click="topCompareFileClick(index)"
        >
          {{ item.buttonName }}
        </NButton>
      </div>
      <NTabs v-model:value="currentTab" type="line" animated @update:value="tabChangeHandle">
        <NTab v-for="item in errorTypeList" :key="item.id" :name="item.key" :tab="item.title">
          {{ item.title }}({{ item.errorNum }})
        </NTab>
      </NTabs>
      <NSpin :show="showLoading" :description="loadingDes" :rotate="false" size="large">
        <template #icon>
          <img src="@/assets/imgs/spin-loading.gif" alt="" width="240" height="240" />
        </template>
        <div class="mt-20px flex">
          <div v-if="isBack" class="content-box bg-white"></div>
          <div v-else class="content-box">
            <div class="error-box">
              <div class="error-title">异常项</div>
              <div v-if="currentErrorList.length > 0" class="error-content-box">
                <NScrollbar class="h-530px">
                  <div
                    v-for="(item, index) in currentErrorList"
                    :key="item.id"
                    class="error-item"
                    :class="currentErrorIndex === index ? 'error-item-active' : ''"
                    @click="locateSentenceClick(item, index)"
                  >
                    异常项{{ index + 1 }}
                  </div>
                </NScrollbar>
              </div>
              <div v-else class="error-content-box">
                <NEmpty class="mt-200px" description="暂无异常项" />
              </div>
            </div>
            <div class="editor-box w-726px flex flex-col">
              <div class="title-box">
                <div class="file-title">基准文件：{{ bidUnitData.fileName }}</div>
                <div v-if="currentErrorData && currentTab === 'pizhu'">
                  <NTooltip trigger="hover">
                    <template #trigger>
                      <div class="describe-text">
                        {{ currentErrorData.doc1CommentText }}
                      </div>
                    </template>
                    {{ currentErrorData.doc1CommentText }}
                  </NTooltip>
                </div>
                <div v-if="currentErrorData && currentTab === 'zitizihao'">
                  <NTooltip trigger="hover">
                    <template #trigger>
                      <div class="describe-text">
                        {{ currentErrorData.fontName1 }}&nbsp;{{ currentErrorData.fontSize1 }}
                      </div>
                    </template>
                    {{ currentErrorData.fontName1 + '&nbsp;' + currentErrorData.fontSize1 }}
                  </NTooltip>
                </div>
              </div>
              <VueUeditorWrap
                v-model="leftContentHtml"
                editor-id="left_editor"
                :config="editorConfig"
                :editor-dependencies="editorDependencies"
                @ready="leftReadyHandle"
              />
              <div v-if="specialData && (currentTab === 'zuozhe' || currentTab === 'shijian')" class="special-box">
                <div class="special-text">作者：{{ specialData.author1 }}</div>
                <div class="special-text">最后一次保存者：{{ specialData.lastModifiedBy1 }}</div>
                <div class="special-text">创建时间：{{ specialData.createdTime1 }}</div>
                <div class="special-text">最后一次保存时间：{{ specialData.modifiedTime1 }}</div>
              </div>
            </div>
            <div class="editor-box w-726px flex flex-col">
              <div class="title-box">
                <div class="file-title">投标单位{{ compareFile.compareNum }}：{{ compareFile.fileName }}</div>
                <div v-if="currentErrorData && currentTab === 'pizhu'">
                  <NTooltip trigger="hover">
                    <template #trigger>
                      <div class="describe-text">
                        {{ currentErrorData.doc2CommentText }}
                      </div>
                    </template>
                    {{ currentErrorData.doc2CommentText }}
                  </NTooltip>
                </div>
                <div v-if="currentErrorData && currentTab === 'zitizihao'">
                  <NTooltip trigger="hover">
                    <template #trigger>
                      <div class="describe-text">
                        {{ currentErrorData.fontName2 }}&nbsp;{{ currentErrorData.fontSize2 }}
                      </div>
                    </template>
                    {{ currentErrorData.fontName2 + '&nbsp;' + currentErrorData.fontSize2 }}
                  </NTooltip>
                </div>
                <div
                  v-if="
                    currentErrorData && (currentTab === 'zhengwen' || currentTab === 'mulu' || currentTab === 'tupian')
                  "
                >
                  <div class="describe-text">
                    相似比例：{{ currentErrorData.plagiarismRateNum }}%
                  </div>
                </div>
              </div>
              <VueUeditorWrap
                v-model="rightContentHtml"
                editor-id="right_editor"
                :config="editorConfig"
                :editor-dependencies="editorDependencies"
                @ready="rightReadyHandle"
              />
              <div v-if="specialData && (currentTab === 'zuozhe' || currentTab === 'shijian')" class="special-box">
                <div class="special-text">作者：{{ specialData.author2 }}</div>
                <div class="special-text">最后一次保存者：{{ specialData.lastModifiedBy2 }}</div>
                <div class="special-text">创建时间：{{ specialData.createdTime2 }}</div>
                <div class="special-text">最后一次保存时间：{{ specialData.modifiedTime2 }}</div>
              </div>
            </div>
          </div>
        </div>
      </NSpin>
    </div>
  </NModal>
</template>

<style scoped lang="scss">
.top-btn-box {
  border-radius: 20px 20px 0 0;
  overflow: hidden;
  background-color: white;
  margin-bottom: 10px;
  .head-btn {
    height: 50px;
    padding: 0 23px;
    font-weight: 400;
    font-size: 18px;
    background: #f7f6fa;
    color: #836fff;
    line-height: 50px;
    border-radius: 0;
    margin: 0 1px;
  }
  .head-btn:last-child {
    border-radius: 0 20px 0 0;
    overflow: hidden;
  }
  .head-btn-active {
    background: #836fff;
    color: #ffffff;
  }
  .head-btn:hover {
    background: #836fff;
    color: #ffffff;
  }
}
.content-box {
  width: 100%;
  display: flex;
  flex-direction: row;
  align-items: center;
  .error-box {
    width: 200px;
    height: 100%;
    border: 1px solid #eeeeee;
    border-radius: 4px;
    .error-title {
      font-size: 20px;
      font-weight: bolder;
      color: #333333;
      line-height: 40px;
      text-align: center;
      border-bottom: 1px solid #eeeeee;
    }
    .error-content-box {
      display: flex;
      flex-direction: column;
      .error-item {
        line-height: 40px;
        font-size: 16px;
        padding: 0 10px;
        color: #333333;
        white-space: nowrap;
        overflow: hidden;
        text-overflow: ellipsis;
        cursor: pointer;
      }
      .error-item-active {
        background: #e8ecfd;
        color: #836fff;
      }
    }
  }
  .editor-box {
    border: 1px solid #eeeeee;
    border-radius: 4px;
    position: relative;
    .special-box {
      position: absolute;
      display: flex;
      flex-direction: column;
      padding: 15px 25px;
      background: white;
      left: 0;
      right: 0;
      top: 41px;
      bottom: 0;
      z-index: 1000;
      .special-text {
        font-size: 18px;
        font-weight: 400;
        color: #333333;
        line-height: 40px;
      }
    }
  }
  .title-box {
    display: flex;
    flex-direction: row;
    align-items: center;
    justify-content: space-between;
    padding: 0 15px;
    border-bottom: 1px solid #eeeeee;
    width: 100%;
    .file-title {
      font-size: 20px;
      font-weight: bolder;
      color: #333333;
      line-height: 40px;
      width: calc(100% - 200px);
      white-space: nowrap;
      overflow: hidden;
      text-overflow: ellipsis;
    }
    .describe-text {
      font-size: 18px;
      font-weight: 400;
      color: #ff7575;
      line-height: 40px;
      cursor: pointer;
      max-width: 150px;
      text-align: right;
      white-space: nowrap;
      overflow: hidden;
      text-overflow: ellipsis;
    }
  }
}
:deep(.n-upload) {
  width: auto;
}
:deep(.edui-default .edui-editor) {
  border: none !important;
}
:deep(.edui-editor) {
  width: auto !important;
}
:deep(.edui-editor-iframeholder) {
  width: auto !important;
}
:deep(.n-spin) {
  width: auto;
  height: auto;
}
</style>
